/* eslint-disable no-empty */
// 实现这个项目的构建任务
const { src, dest, parallel, series, watch } = require("gulp");
const del = require("del");
const loadPlugins = require("gulp-load-plugins");
const plugins = loadPlugins();
const bs = require("browser-sync");
const gulpStylelint = require("gulp-stylelint");

const cwd = process.cwd();
let config = {
  build: {
    src: "src",
    dist: "dist",
    temp: "temp",
    public: "public",
    reports: "reports",
    paths: {
      styles: "assets/styles/*.scss",
      scripts: "assets/scripts/*.js",
      pages: "*.html",
      images: "assets/images/**",
      fonts: "assets/fonts/**",
    },
  },
};
try {
  const loadConfig = require(`${cwd}/pages.config.js`);
  config = Object.assign({}, config, loadConfig);
} catch (err) {}

const clean = () => {
  return del([config.build.dist, config.build.temp, config.build.reports]);
};

const style = () => {
  return src(config.build.paths.styles, {
    base: config.build.src,
    cwd: config.build.src,
  })
    .pipe(plugins.sass({ outputStyle: "expanded" })) //样式中结尾花括号}换行
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({ stream: true }));
};

const stylesLint = () => {
  return src(config.build.paths.styles, {
    base: config.build.src,
    cwd: config.build.src,
  }).pipe(
    gulpStylelint({
      failAfterError: false,
      reportOutputDir: "reports/csslint",
      reporters: [
        { formatter: "string", console: true },
        { formatter: "verbose", console: true },
        { formatter: "json", save: "report.json" },
      ],
      debug: false,
    })
  );
};

const script = () => {
  return src(config.build.paths.scripts, {
    base: config.build.src,
    cwd: config.build.src,
  })
    .pipe(plugins.babel({ presets: ["@babel/preset-env"] })) //@babel/preset-env能将最新的语法转换为ecmascript5的写法
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({ stream: true }));
};

const scriptsLint = () => {
  return src(config.build.paths.scripts, {
    base: config.build.src,
    cwd: config.build.src,
  })
    .pipe(plugins.eslint())
    .pipe(plugins.eslint.format())
    .pipe(plugins.eslint.failAfterError());
};

const page = () => {
  return src(config.build.paths.pages, {
    base: config.build.src,
    cwd: config.build.src,
  })
    .pipe(plugins.swig({ data: config.data, defaults: { cache: false } })) // 防止模板缓存导致页面不能及时更新
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({ stream: true }));
};

const image = () => {
  return src(config.build.paths.images, {
    base: config.build.src,
    cwd: config.build.src,
  })
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist));
};

const font = () => {
  return src(config.build.paths.fonts, {
    base: config.build.src,
    cwd: config.build.src,
  })
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist));
};

const extra = () =>
  src("**", { base: config.build.public, cwd: config.build.public }).pipe(
    dest(config.build.dist)
  );
const lint = parallel(stylesLint, scriptsLint);
const devServe = () => {
  watch(config.build.paths.styles, style);
  watch(config.build.paths.scripts, script);
  watch(config.build.paths.pages, page);
  // watch('src/assets/images/**', image)
  // watch('src/assets/fonts/**', font)
  // watch('public/**', extra)
  watch([config.build.paths.images, config.build.paths.fonts], bs.reload);
  watch("**", { cwd: config.build.public }, bs.reload);

  bs.init({
    notify: false,
    port: 2020,
    //open: false,
    server: {
      baseDir: [
        config.build.temp,
        config.build.dist,
        config.build.public,
        config.build.src,
      ],
      routes: {
        "/node_modules": "node_modules",
      },
    },
  });
};
const useref = () => {
  return src(config.build.paths.pages, {
    base: config.build.temp,
    cwd: config.build.temp,
  })
    .pipe(plugins.useref({ searchPath: [config.build.temp, "."] }))
    .pipe(dest(config.build.dist))
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    .pipe(
      plugins.if(
        /\.html$/,
        plugins.htmlmin({
          collapseWhitespace: true,
          minifyCSS: true,
          minifyJS: true,
        })
      )
    )
    .pipe(dest(config.build.dist));
};

const prodServe = () => {
  bs.init({
    notify: false,
    port: 2020,
    //open: true,
    server: {
      baseDir: config.build.dist,
    },
  });
};
const publish = () => {
  return src("**", { base: config.build.dist, cwd: config.build.dist }).pipe(
    plugins.ghPages()
  );
};

const compile = parallel(style, script, page);
const build = series(
  clean,
  parallel(series(compile, useref), extra, image, font)
);
const start = series(build, prodServe);
const serve = series(clean, compile, devServe);
const deploy = series(build, publish);
module.exports = {
  clean,
  serve,
  lint,
  build,
  start,
  deploy,
};
